package com.xingzhe.learning.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xingzhe.base.exception.XingZhePlusException;
import com.xingzhe.base.model.PageResult;
import com.xingzhe.content.model.po.CoursePublish;
import com.xingzhe.learning.feignclient.ContentServiceClient;
import com.xingzhe.learning.mapper.XcChooseCourseMapper;
import com.xingzhe.learning.mapper.XcCourseTablesMapper;
import com.xingzhe.learning.model.dto.MyCourseTableParams;
import com.xingzhe.learning.model.dto.XcChooseCourseDto;
import com.xingzhe.learning.model.dto.XcCourseTablesDto;
import com.xingzhe.learning.model.po.XcChooseCourse;
import com.xingzhe.learning.model.po.XcCourseTables;
import com.xingzhe.learning.service.MyCourseTablesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
@Slf4j
@Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService {
    @Resource
    XcChooseCourseMapper chooseCourseMapper;

    @Resource
    XcCourseTablesMapper courseTablesMapper;

    @Resource
    ContentServiceClient contentServiceClient;

    @Transactional
    @Override
    public XcChooseCourseDto addChooseCourse(String userId, Long courseId) {
        //调用管理内容查询课程的收费规则
        CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId);
        if (coursepublish==null){
            XingZhePlusException.cast("课程不存在");
        }
        XcChooseCourse chooseCourse =null;
        //收费的规则
        String charge = coursepublish.getCharge();
        if (charge.equals("201000")){
            //如果是免费课程，会直接向选课记录表、我的课程表写入数据
            //添加免费课程
             chooseCourse = addFreeCourse(userId, coursepublish);
            //添加到我的课程表
            XcCourseTables xcCourseTables = addCourseTables(chooseCourse);

        }else {
            //如果是收费课程，会向选课记录表写入数据
            chooseCourse  = addChargeCourse(userId, coursepublish);
        }

        //判断学生的学习资格
        XcCourseTablesDto courseTablesDto = getLearningStatus(userId, courseId);

        //构造返回值
        XcChooseCourseDto xcChooseCourseDto = new XcChooseCourseDto();
        BeanUtils.copyProperties(chooseCourse,xcChooseCourseDto);
        xcChooseCourseDto.setLearnStatus(courseTablesDto.getLearnStatus());
        return xcChooseCourseDto;
    }

    @Override
    public XcCourseTablesDto getLearningStatus(String userId, Long courseId) {
        //学习资格，[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}]
        XcCourseTablesDto courseTablesDto = new XcCourseTablesDto();
        //查询我的课程表，如果查不到则说明没有选课
        XcCourseTables courseTables = getXcCourseTables(userId, courseId);
        if (courseTables==null){
            //"code":"702002","desc":"没有选课或选课后没有支付
            courseTablesDto.setLearnStatus("702002");
            return courseTablesDto;
        }
        //如果查到了，判断是否过期，过期了则不能学习该课程，没则可以继续学习
        boolean before = courseTables.getValidtimeEnd().isBefore(LocalDateTime.now());
        BeanUtils.copyProperties(courseTables,courseTablesDto);
        if (before){
            //code":"702003","desc":"已过期需要申请续期或重新支付"}
            courseTablesDto.setLearnStatus("702003");
        }else{
            //"code":"702001","desc":"正常学习"
            courseTablesDto.setLearnStatus("702001");
        }
        return courseTablesDto;
    }

    @Transactional
    @Override
    public boolean saveChooseCourseSuccess(String chooseCourseId) {
        //根据选课id查询选课表
        XcChooseCourse xcChooseCourse = chooseCourseMapper.selectById(chooseCourseId);
        if (xcChooseCourse==null){
            log.debug("接受到购买课程的消息，根据选课id在数据库找不到选课记录，选课id:{}",chooseCourseId);
            return false;
        }
        //选课状态
        String status = xcChooseCourse.getStatus();
        //判断是否已经支付
        if (status.equals("701002")){
            //待支付,所以将他更新为已支付
            xcChooseCourse.setStatus("701001");
            int i = chooseCourseMapper.updateById(xcChooseCourse);
            if (i<=0){
                log.debug("添加选课记录失败：{}",xcChooseCourse);
                XingZhePlusException.cast("添加选课记录失败");
            }
            //并且向我的课程表插入该课记录
            XcCourseTables xcCourseTables = addCourseTables(xcChooseCourse);
            return true;
        }
        return false;
    }

    @Override
    public PageResult<XcCourseTables> mycoursetables(MyCourseTableParams params) {
        String userId = params.getUserId();
        //当前的页码
        int pageNo = params.getPage();
        //每页记录数
        int size = params.getSize();
        Page<XcCourseTables> objectPage = new Page<>(pageNo, size);
        LambdaQueryWrapper<XcCourseTables> queryWrapper = new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId,userId);
        //分页查询
        Page<XcCourseTables> pageResult = courseTablesMapper.selectPage(objectPage, queryWrapper);
        List<XcCourseTables> records = pageResult.getRecords();
        //记录总数
        long total = pageResult.getTotal();
        PageResult<XcCourseTables> courseTablesResult = new PageResult<>(records, total, pageNo, size);
        return courseTablesResult;
    }

    /**
     * 添加免费课程，免费课程加入选课记录表、我的课程表
     * @param userId  用户id
     * @param coursePublish 已发布的课程
     * @return  XcChooseCourse
     */
    public XcChooseCourse addFreeCourse(String userId,CoursePublish coursePublish){
        //如果是免费的课程且已经选课成功，就不用添加了
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<XcChooseCourse>()
                .eq(XcChooseCourse::getCourseId, coursePublish.getId())
                .eq(XcChooseCourse::getOrderType, "700001")//免费课程
                .eq(XcChooseCourse::getStatus, "701001");//选课成功
        List<XcChooseCourse> xcChooseCourses = chooseCourseMapper.selectList(queryWrapper);
        //如果该免费课程已经有了，就直接返回他
        if (xcChooseCourses.size()>0){
            return xcChooseCourses.get(0);
        }
        //没有，则向选课表写记录
        XcChooseCourse chooseCourse = new XcChooseCourse();
        chooseCourse.setCourseName(coursePublish.getName());
        chooseCourse.setCourseId(coursePublish.getId());
        chooseCourse.setUserId(userId);
        chooseCourse.setCompanyId(coursePublish.getCompanyId());
        chooseCourse.setOrderType("700001");//免费课程
        chooseCourse.setCreateDate(LocalDateTime.now());
        chooseCourse.setCoursePrice(coursePublish.getPrice());
        chooseCourse.setValidDays(365);//有效期的总时间
        chooseCourse.setStatus("701001");//选课成功
        chooseCourse.setValidtimeStart(LocalDateTime.now());//有效期的开始时间
        chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));//有效期的结束时间
        int insert = chooseCourseMapper.insert(chooseCourse);
        if (insert<=0){
            XingZhePlusException.cast("添加选课记录失败");
        }
        return chooseCourse;
    }

    /**
     * 添加到我的课程表
     * @param xcChooseCourse    我的课程表
     * @return XcChooseCourse
     */
    public XcCourseTables addCourseTables(XcChooseCourse xcChooseCourse){
        //选课成功了才可以向我的课程表添加数据
        if (!xcChooseCourse.getStatus().equals("701001")){
            XingZhePlusException.cast("选课没有成功，无法添加到我的课程表");
        }
        XcCourseTables courseTables = getXcCourseTables(xcChooseCourse.getUserId(), xcChooseCourse.getCourseId());
        if (courseTables!=null){
            return courseTables;
        }
        XcCourseTables xcCourseTables = new XcCourseTables();
        BeanUtils.copyProperties(xcChooseCourse,xcCourseTables);
        xcCourseTables.setChooseCourseId(xcChooseCourse.getId());
        xcCourseTables.setCourseType(xcChooseCourse.getOrderType());
        xcCourseTables.setUpdateDate(LocalDateTime.now());
        int insert = courseTablesMapper.insert(xcCourseTables);
        if (insert<=0){
            XingZhePlusException.cast("将选课记录添加到我的课程表失败");
        }
        return xcCourseTables;
    }

    /**
     * @description 根据课程和用户查询我的课程表中某一门课程
     * @param userId
     * @param courseId
     * @return com.xingzhe.learning.model.po.XcCourseTables
     * @author Mr.M
     * @date 2022/10/2 17:07
     */
    public XcCourseTables getXcCourseTables(String userId,Long courseId){
        XcCourseTables xcCourseTables = courseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId).eq(XcCourseTables::getCourseId, courseId));
        return xcCourseTables;

    }


    /**
     * 添加收费课程
     * @param userId 用户id
     * @param coursePublish 已发布的课程
     * @return XcChooseCourse
     */
    public XcChooseCourse addChargeCourse(String userId,CoursePublish coursePublish){
        //如果是收费的课程且已经选课状态为待支付，就不用添加了
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<XcChooseCourse>()
                .eq(XcChooseCourse::getCourseId, coursePublish.getId())
                .eq(XcChooseCourse::getOrderType, "700002")//收费课程
                .eq(XcChooseCourse::getStatus, "701002");//待支付
        List<XcChooseCourse> xcChooseCourses = chooseCourseMapper.selectList(queryWrapper);
        //如果该免费课程已经有了，就直接返回他
        if (xcChooseCourses.size()>0){
            return xcChooseCourses.get(0);
        }
        //没有，则向选课表写记录
        XcChooseCourse chooseCourse = new XcChooseCourse();
        chooseCourse.setCourseName(coursePublish.getName());
        chooseCourse.setCourseId(coursePublish.getId());
        chooseCourse.setUserId(userId);
        chooseCourse.setCompanyId(coursePublish.getCompanyId());
        chooseCourse.setOrderType("700002");//收费课程
        chooseCourse.setCreateDate(LocalDateTime.now());
        chooseCourse.setCoursePrice(coursePublish.getPrice());
        chooseCourse.setValidDays(365);//有效期的总时间
        chooseCourse.setStatus("701002");//待支付
        chooseCourse.setValidtimeStart(LocalDateTime.now());//有效期的开始时间
        chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));//有效期的结束时间
        int insert = chooseCourseMapper.insert(chooseCourse);
        if (insert<=0){
            XingZhePlusException.cast("添加选课记录失败");
        }
        return chooseCourse;
    }
}
